/*********************************************************
 * This class is one of the various GUI frames that will
 * aid the user in tracking their workouts.
 *********************************************************/ 
package gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicBorders;

import misc.AutoComplete;

import workoutModel.weightliftingSet;
import workoutModel.workoutSet;
import database.DB_connection;


/*************************************************************
 * This class creates a JPanel that will allow the user to
 * keep track of their workout plan for the day.  The 
 * format will make so that the user has an easy time 
 * inputting their workout later.  Also, this JPanel will
 * call previousWorkoutGUI to generate a list of 
 * past performances related to the workout plan.  The 
 * format should be printable above all else.
 * 
 * @author Brian Renzenbrink
 * @author Evan Nelson
 *
 *************************************************************/
public class Content_WeightliftingChart extends JPanel implements Printable{

	private boolean editting = false;
	private Color textFieldBG = Color.WHITE;
	private Border textFieldBorder = null; 
	
	private Dimension size;

	private final Color DIMMEDBGCOLOR = Color.LIGHT_GRAY;
	private final Color NONDIMMEDBGCOLOR = Color.WHITE;
	private final Color ACTIVECOLOR = Color.YELLOW;

	private final Border dimmedBorder = new BasicBorders.FieldBorder(Color.LIGHT_GRAY, Color.LIGHT_GRAY, Color.LIGHT_GRAY, Color.LIGHT_GRAY);
	private final Border nonDimmedBorder = new BasicBorders.FieldBorder(Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK);
	
	private static final long serialVersionUID = 3149825197719836766L;
	final boolean shouldFill = true;
	final boolean shouldWeightX = true;
	final boolean RIGHT_TO_LEFT = false;
	
	private boolean changesMade = false;
	private int currentRow = 0;
	
	private DB_connection conn;
	
	//location of workout textarea
	private JComboBox locationArea;

	//Collections of all exercise data fields created
	private ArrayList <JComboBox>exerciseFields = new ArrayList<JComboBox>();
	private ArrayList <JComboBox>weightTypeFields = new ArrayList<JComboBox>();
	private ArrayList <JTextArea>weightFields = new ArrayList<JTextArea>();
	private ArrayList <JTextArea>repsFields = new ArrayList<JTextArea>();
	private ArrayList <JTextArea>notesFields = new ArrayList<JTextArea>();

	private ArrayList<String> DB_exercises = new ArrayList<String>();
	private ArrayList<String> DB_weightTypes = new ArrayList<String>();
	private ArrayList<String> DB_locations = new ArrayList<String>();

	

	/*****************************************************************
	 * A constructor for creating a workout chart jframe
	 *****************************************************************/
	public Content_WeightliftingChart(boolean editting, Dimension size){
		
		this.editting = editting;
		this.size = size;
		
		if(editting) {
//			Make textfield backgrounds white when editting, add border
			this.textFieldBG = NONDIMMEDBGCOLOR;
			this.textFieldBorder = nonDimmedBorder;
		} else {
//			Gray out certain JTextFields when not editting, no border
			this.textFieldBG = DIMMEDBGCOLOR;
			this.textFieldBorder = dimmedBorder;
		}
		conn = new DB_connection();
		System.out.println("Testing the basic gui frame.");
		initialize();
	}
	
	private void setExercises() {
		//Use conn to query the database for all exercises
		ResultSet rs;
		rs = conn.executeCurrentStatement("SELECT DISTINCT Exercise FROM Weightlifting ORDER BY Exercise");
		DB_exercises.add("");
		System.out.println("Display all exercises:");
		try{
			while(rs.next()){
				String str = rs.getString("Exercise");
				System.out.println(str);
				DB_exercises.add(str);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void setWeightTypes() {
		//Use conn to query the database for all weight types
		ResultSet rs;
		rs = conn.executeCurrentStatement("SELECT weightType FROM WeightType");
		DB_weightTypes.add("");
		System.out.println("Building weight types list:");
		try{
			while(rs.next()){
				String str = rs.getString("weightType");
				System.out.println(str);
				DB_weightTypes.add(str);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void setLocations() {
		//Use conn to query the database for all locations
		ResultSet rs;
		rs = conn.executeCurrentStatement("SELECT name FROM Location ORDER BY name");
		DB_locations.add("");
		System.out.println("Display all locations:");
		try{
			while(rs.next()){
				String str = rs.getString("name");
				System.out.println(str);
				DB_locations.add(str);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/*****************************************************************
	 * An initialization method for the workout chart
	 *****************************************************************/
	public void initialize(){
		//Grab data from the database
		setExercises();
		setWeightTypes();
		setLocations();
		
		//Create and set up the window.
		setSize(this.size);
		addComponentsToPane();

		setVisible(true);
	}

	/******************************************************************************
	 * This method will add a new group of labels and textfields at the bottom 
	 * of the current frame.
	 ******************************************************************************/
	private void addNewSet(){
		System.out.println("Create another line of text fields for user input.");  
		GridBagConstraints c = new GridBagConstraints();

		//The data row - Contains textfields for Exercise, Weight Type, Weight, Reps, and Notes
		JComboBox exerciseCB = new AutoComplete(DB_exercises.toArray());
		exerciseCB.setEditable(true);
		exerciseCB.getEditor().getEditorComponent().addFocusListener(new ComboBoxHighlighter());
		
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;       
		c.gridy = currentRow;  
		add(exerciseCB, c);
		exerciseFields.add(exerciseCB);
		
		//TODO: validate exerciseCB to make sure they entered a proper value
		
		JComboBox weightTypeCB = new AutoComplete(DB_weightTypes.toArray());      
		weightTypeCB.setEditable(true);
		weightTypeCB.getEditor().getEditorComponent().addFocusListener(new ComboBoxHighlighter());
		
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 1;       
		c.gridy = currentRow;  
		add(weightTypeCB, c);
		weightTypeFields.add(weightTypeCB);
		
//		TODO: validate weightTypeCB to make sure they entered a proper value
		
		
		JTextArea weightArea = new JTextArea();
		weightArea.setEditable(this.editting);
		weightArea.setBackground(this.textFieldBG);
		weightArea.setBorder(this.textFieldBorder);
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(1,3,1,3);  //top padding
		c.gridx = 2;       
		c.gridy = currentRow;     
		add(weightArea, c);
		weightFields.add(weightArea);


		weightArea.addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				char c = e.getKeyChar();
				
//				Ensure that only numbers are entered into weight field
			    if (!((Character.isDigit(c) ||
			    		(c == KeyEvent.VK_BACK_SPACE) ||
			    		(c == KeyEvent.VK_DELETE)))) {
			    			getToolkit().beep();
			    			e.consume();
			    }
			}
		});
		
//		If editting, highlight this field when focus is gained
		if(this.editting) {
			weightArea.addFocusListener(new TextAreaHighlighter());
		}

		
		JTextArea repsArea = new JTextArea();
		repsArea.setEditable(this.editting);
		repsArea.setBackground(this.textFieldBG);
		repsArea.setBorder(this.textFieldBorder);
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(1,3,1,3);  //top padding
		c.gridx = 3;
		c.gridy = currentRow;
		add(repsArea, c);
		repsFields.add(repsArea);
		
//		Ensure that only numbers are entered into reps field
		repsArea.addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				char c = e.getKeyChar();
			    if (!((Character.isDigit(c) ||
			    		(c == KeyEvent.VK_BACK_SPACE) ||
			    		(c == KeyEvent.VK_DELETE)))) {
			    			getToolkit().beep();
			    			e.consume();
			    }
			}
		});
		
//		If editting, highlight this field when focus is gained
		if(this.editting) {
			repsArea.addFocusListener(new TextAreaHighlighter());
		}

		JTextArea notesArea = new JTextArea();
		notesArea.setEditable(this.editting);
		notesArea.setBackground(this.textFieldBG);
		notesArea.setBorder(this.textFieldBorder);
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(1,3,1,3);  //top padding
		c.gridx = 4;       
		c.gridy = currentRow;     
		add(notesArea, c);
		notesFields.add(notesArea);
		
//		If editting, highlight this field when focus is gained
		if(this.editting) {
			notesArea.addFocusListener(new TextAreaHighlighter());
		}
		
		currentRow++;
		validate();
	}
	/******************************************************************************
	 * This is the event handler for the user pressing the 'add new set' button.
	 * 
	 * @param evt
	 ******************************************************************************/
	private void newExerciseButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                  
		addNewSet();
	} 
	
	/******************************************************************************
	 * This is the event handler for the user pressing the 'save' button.
	 * 
	 * @param evt
	 ******************************************************************************/
	private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {
		saveData();
	}
	
	private boolean saveData() {
//		TODO do not hardcode personID!
		int personID = 1;
		String sDate = new java.text.SimpleDateFormat("yyyy/MM/dd").format(new java.util.Date());
		String sLocation = null;
		String sExercise = null;
		String sWeightType = null;
		int nWeight = -1;
		int nReps = -1;
		String sNotes = null;
		
		if(!changesMade) {
			//no changes to save
			return true;
		}
		
		//TODO validate location field
		if(this.locationArea.getSelectedItem().toString() == "") {
			//TODO throw up an error about empty location
			return false;
		}
		
		
		//check to make sure the location exists in Location table; if not, add it
		sLocation = this.locationArea.getSelectedItem().toString();
		ResultSet rs = conn.executeCurrentStatement("SELECT * FROM Location WHERE name = '" + sLocation + "'");
		try {
			rs.last();
			if(rs.getRow() == 0) {
				conn.executeCurrentUpdate("INSERT INTO Location(name) VALUES('" + sLocation + "')");
			}
		} catch(Exception e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
		
		
		//make sure no fields are invalid before we start saving
		for(int i = 4; i <= this.currentRow; i++) {
			if(!isValidRow(i)) {
				//TODO: throw up an error about bad data;
			}
		}

		Object exercises[] = exerciseFields.toArray();
		Object weightTypes[] = weightTypeFields.toArray();
		Object weights[] = weightFields.toArray();
		Object reps[] = repsFields.toArray();
		Object notes[] = notesFields.toArray();
		
		//data is all good; let's start saving it
		for(int i = 0; i < this.currentRow - 4; i++) {
			sExercise =  ((JComboBox)exercises[i]).getSelectedItem().toString();
			sWeightType = ((JComboBox)weightTypes[i]).getSelectedItem().toString();
			nWeight = Integer.parseInt(((JTextArea)weights[i]).getText());
			nReps = Integer.parseInt(((JTextArea)reps[i]).getText());
			sNotes = ((JTextArea)notes[i]).getText();
			
			//build our SQL update statement
			String sql = "INSERT INTO Weightlifting(PersonID, Exercise, WeightType, Sequence, Weight, Reps, DateRecorded, Location, Notes)"
				+ " VALUES("
				+ personID
				+ ", '" + sExercise + "'"
				+ ", '" + sWeightType + "'"
				+ "," + new Integer(i+1) 	// sequence (a.k.a. "Order")
				+ "," + nWeight
				+ "," + nReps
				+ ", '" + sDate + "'"
				+ ", '" + sLocation + "'"
				+ ", '" + sNotes + "'"
				+ ")";
			
			System.out.println("Executing SQL: " + sql);
			
			conn.executeCurrentUpdate(sql);
		}
		
		//now that changes are saved, reset changesMade
		changesMade = false;
		return true;
	} 

	private boolean isValidRow(int i) {
		// TODO check fields to ensure valid data
		return false;
	}
	
	/**************************************************************************
	 * This method generates a previousWorkoutGUI using the user input.  
	 * @param evt
	 **************************************************************************/
	private void newPWButtonActionPerformed(java.awt.event.ActionEvent evt){
		//The arraylist of workouts
		ArrayList<weightliftingSet> ws = new ArrayList<weightliftingSet>();
		
		
		//A string representation of each unique pair of exercise and weight type
		//Uses the format 'exercise#weightType'	
		Set<String> uniquePair = new LinkedHashSet<String>();							

		Iterator<JComboBox> iteratorEF;			//Iterator over all exercise fields
		Iterator<JComboBox> iteratorWT;			//Iterator over all weight type fields
		Iterator<String> iteratorUP;				//Iterator over all unique pairs 
		ResultSet rs;								//Our query resultset
		Date date;									//A date object		

		//String representations of our previous set's exercise, weight type, and weight
		String ex = null;
		String wt = null;
		double w;	
		String loc = null;
		int r, order;										//The reps associated with the a previous set

		//Create the iterators
		iteratorEF = exerciseFields.iterator();    
		iteratorWT = weightTypeFields.iterator();

		System.out.println( "Exercise-WeightType-Weight-Reps-Date");
		try {
			//Pair up exercises with their associated weight types in the uniquePair set
			while (iteratorEF.hasNext()){
				while (iteratorWT.hasNext()){
					ex = iteratorEF.next().getSelectedItem().toString();
					wt = iteratorWT.next().getSelectedItem().toString();
					System.out.println("ex= " + ex + "wt= " +wt);
					if( !uniquePair.add(ex+"#"+wt)){
						System.out.println("A duplicate pair!");
					}
				}
			}

			//Search the database for the most recent entry of each exercise-weight type pair
			//Select all of the most recent matching exercise-weightType pairs
			iteratorUP = uniquePair.iterator();
			while(iteratorUP.hasNext()){
				//Separate the exercise and weight type strings
				ex = iteratorUP.next();
				wt = ex.substring(ex.indexOf('#')+1);
				ex = ex.substring(0, ex.indexOf('#'));

				try {
					//If the exercise field is empty
					if( !ex.isEmpty()){
						//If the weight type is null, use this sql statement
						if(wt.isEmpty()){
							//Get the most recent date of that exercise using that weight type
							rs = conn.executeCurrentStatement("SELECT MAX(dateRecorded) FROM Weightlifting"
									+ " WHERE exercise = '" + ex + "' AND weightType IS NULL");

							rs.next();
							date = rs.getDate("MAX(dateRecorded)");

							//Get the exercise, weight type, and weight for the exercise
							rs = conn.executeCurrentStatement("SELECT exercise, weightType, weight, reps, location, sequence FROM Weightlifting"
									+ " WHERE exercise = '" + ex + "' AND weightType IS NULL and dateRecorded = '"
									+ date.toString() + "' ORDER BY sequence");
						}
						//Else, use this sql statement
						else{
							//Get the most recent date of that exercise using that weight type
							rs = conn.executeCurrentStatement("SELECT MAX(dateRecorded) FROM Weightlifting "
									+ "WHERE exercise = '" + ex + "' AND weightType = '" + wt + "' ORDER BY dateRecorded");

							rs.next();
							date = rs.getDate("MAX(dateRecorded)");

							//Get the exercise, weight type, and weight for the exercise
							rs = conn.executeCurrentStatement("SELECT exercise, weightType, weight, reps, location, sequence FROM Weightlifting"
									+ " WHERE exercise = '" + ex + "' AND weightType = '" + wt + "' AND dateRecorded = '"  
									+ date.toString() + "' ORDER BY sequence");
						}

						System.out.println( "---------------------------------");
						//Output the previous exercises
						while(rs.next()){
							ex = rs.getString("exercise");
							wt = rs.getString("weightType");
							w = rs.getDouble("weight");
							r = rs.getInt("reps");
							loc = rs.getString("location");
							order = rs.getInt("sequence");
							
							weightliftingSet currentSet = new weightliftingSet(date, ex, null, loc, order, r, w, wt);
							ws.add(currentSet);
							System.out.println(currentSet.toString());
						}//end while loop
					}//end if
					else{
						System.out.println("The exercise field is empty.  Ignoring this set.");
					}//end else
				}catch (NullPointerException e) {
					System.out.println("You have never done " + ex + " using " + wt + " before.");
				}//end catch
			}//end while loop
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		previousWorkoutGUI pwg = new previousWorkoutGUI(ws);
		System.out.println("Save button pressed");
	}//end newPWButtonActionPerformed 


	/******************************************************************************
	 * This is the event handler for the user pressing the 'print' button.
	 * 
	 * @param evt
	 ******************************************************************************/
	private void printButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                  
		PrinterJob job = PrinterJob.getPrinterJob();
		PageFormat pf = job.defaultPage();
		pf.setOrientation(PageFormat.LANDSCAPE);
		job.setPrintable(this, pf);
        boolean ok = job.printDialog();
        if (ok) {
        	try {
        		job.print();
            } catch (PrinterException ex) {
            	/* The job did not successfully complete */
            	JOptionPane.showMessageDialog(null, "An error occured when trying to print, please try printing again. If the error persists, contact the program developers. (File->About)", "Error Printing", JOptionPane.ERROR_MESSAGE);
            }
        }
	} 
	
	/******************************************************************
	 * This method prints the entire UI.
	 * @param pane: The pane to add the components to.
	 ******************************************************************/
	public int print(Graphics g, PageFormat pf, int page) {
		
		if (page > 0) { /* We have only one page, and 'page' is zero-based */
            return NO_SUCH_PAGE;
        }

        /* User (0,0) is typically outside the imageable area, so we must
         * translate by the X and Y values in the PageFormat to avoid clipping
         */
        Graphics2D g2d = (Graphics2D)g.create();
        g2d.translate(pf.getImageableX(), pf.getImageableY());
        
//      We need to scale the image properly so that it fits on one page.
        double xScale = pf.getImageableWidth() / getWidth();
        double yScale = pf.getImageableHeight() / getHeight();
        
//      Maintain the aspect ratio by taking the min of those 2 factors and using it to scale both dimensions.
        double aspectScale = Math.min(xScale, yScale);
        g2d.scale(aspectScale, aspectScale);
        
        //temporarily make the background white so we're not forced to print gray everywhere
        Color curBG = getBackground();
        setBackground(Color.WHITE);
        
        //temporarily make all dimmed textboxes into non-dimmed textboxes
        if(!this.editting) {
            locationArea.setBackground(NONDIMMEDBGCOLOR);
            locationArea.setBorder(nonDimmedBorder);
            for(JTextArea area : this.weightFields) {
            	area.setBackground(NONDIMMEDBGCOLOR);
            	area.setBorder(nonDimmedBorder);
            }
            for(JTextArea area : this.repsFields) {
            	area.setBackground(NONDIMMEDBGCOLOR);
            	area.setBorder(nonDimmedBorder);
            }
            for(JTextArea area : this.notesFields) {
            	area.setBackground(NONDIMMEDBGCOLOR);
            	area.setBorder(nonDimmedBorder);
            }
        }
                
        //print everything in the pane
        printAll(g2d);
        
        //return to original background color and textarea colors
        setBackground(curBG);
        if(!this.editting) {
            locationArea.setBackground(DIMMEDBGCOLOR);
            locationArea.setBorder(dimmedBorder);
            for(JTextArea area : this.weightFields) {
            	area.setBackground(DIMMEDBGCOLOR);
            	area.setBorder(dimmedBorder);
            }
            for(JTextArea area : this.repsFields) {
            	area.setBackground(DIMMEDBGCOLOR);
            	area.setBorder(dimmedBorder);
            }
            for(JTextArea area : this.notesFields) {
            	area.setBackground(DIMMEDBGCOLOR);
            	area.setBorder(dimmedBorder);
            }
        }
        
        //tell the caller that this page is part of the printed document
        return PAGE_EXISTS;
	}

	/******************************************************************
	 * This method adds the basic components to a given pane.
	 * @param pane: The pane to add the components to.
	 ******************************************************************/
	public void addComponentsToPane() {
		if (RIGHT_TO_LEFT) {
			setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		}
		setLayout(new GridBagLayout());
		setSize(this.size);
		GridBagConstraints c = new GridBagConstraints();


//		BEGIN ROW TWO -- TITLE
		Font titleFont = new Font(Font.SERIF, Font.BOLD, 14);
		JLabel titleLabel = new JLabel("TODAY'S WORKOUT");
		titleLabel.setFont(titleFont);
		c.anchor = GridBagConstraints.NORTH;
		c.gridy = 1;
		c.gridx = 0;
		c.insets = new Insets(1,3,10,3);  //top padding
		c.gridwidth = 5;
		add(titleLabel, c);
		c.gridwidth = 1;
//		END ROW TWO -- TITLE

//		BEGIN ROW ONE -- BUTTONS
		JButton newPWButton = new JButton();
		newPWButton.setText("Previous Sets");
		newPWButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				newPWButtonActionPerformed(evt);
			}
		});
		c.fill = GridBagConstraints.HORIZONTAL;
		c.ipady = 0;       //reset to default
		c.gridx = 0;       
		c.gridy = 0;       
		add(newPWButton, c);
		
		JButton newExerciseButton = new JButton();
		newExerciseButton.setText("Add New Set");
		newExerciseButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				newExerciseButtonActionPerformed(evt);
			}
		});
		c.ipady = 0;       //reset to default
		c.gridx = 1;       
		c.gridy = 0;       
		add(newExerciseButton, c);
		
		JButton saveButton = new JButton();
		saveButton.setEnabled(this.editting);
		saveButton.setText("Save");
		saveButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				saveButtonActionPerformed(evt);
			}
		});
		c.ipady = 0;       //reset to default
		c.gridx = 3;       
		c.gridy = 0;       
		add(saveButton, c);
		
		
		JButton printButton = new JButton();
		printButton.setText("Print");
		printButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				printButtonActionPerformed(evt);
			}
		});
		c.ipady = 0;       //reset to default
		c.gridx = 4;       
		c.gridy = 0;       
		add(printButton, c);
//		END ROW ONE -- BUTTONS
		
//		BEGIN ROW THREE -- HEADER
		Font sharedFont = new Font(Font.SERIF, Font.PLAIN, 12);
		//Date should be selected in constructor
		JLabel dateLabel = new JLabel(new java.text.SimpleDateFormat("yyyy/MM/dd").format(new java.util.Date()));
		dateLabel.setFont(sharedFont);
		c.anchor = GridBagConstraints.NORTH;
		c.gridy = 2;
		c.gridx = 0;
		add(dateLabel, c);

		JLabel locationLabel = new JLabel("Workout Location:");
		//Location should be selected in constructor
		locationLabel.setFont(sharedFont);
		c.anchor = GridBagConstraints.NORTH;
		c.gridy = 2;
		c.gridx = 2;
		add(locationLabel, c);
		
		this.locationArea = new AutoComplete(DB_locations.toArray());
		locationArea.setEditable(this.editting);
		locationArea.setEnabled(this.editting);
		locationArea.getEditor().getEditorComponent().addFocusListener(new ComboBoxHighlighter());
		c.insets = new Insets(1,3,1,3);  //top padding
		c.gridy = 2;
		c.gridx = 3;
		c.gridwidth = 2;
		add(locationArea, c);
		c.gridwidth = 1;

//		END ROW TWO -- HEADER
		


//		BEGIN ROW FOUR -- COLUMN LABELS
		//The field row - Contains labels for Exercise, Weight Type, Weight, Reps, and Notes
		Font fieldFont = new Font(Font.SERIF, Font.PLAIN, 12);
		JLabel exerciseLabel = new JLabel("Exercise");
		exerciseLabel.setSize(20, 12);
		//exerciseLabel.setFont(fieldFont);
		c.anchor = GridBagConstraints.NORTH;
		c.weightx = 0.5;
		c.gridx = 0;
		c.gridy = 3;
		add(exerciseLabel, c);

		JLabel weightTypeLabel = new JLabel("Weight Type");
		//exerciseLabel.setFont(fieldFont);
		c.anchor = GridBagConstraints.NORTH;
		c.weightx = 0.1;
		c.gridx = 1;
		c.gridy = 3;
		add(weightTypeLabel, c);

		JLabel weightLabel = new JLabel("Weight");
		//exerciseLabel.setFont(fieldFont);
		c.anchor = GridBagConstraints.NORTH;
		c.weightx = 0.1;
		c.gridx = 2;
		c.gridy = 3;
		add(weightLabel, c);

		JLabel repsLabel = new JLabel("Reps");
		//exerciseLabel.setFont(fieldFont);
		c.anchor = GridBagConstraints.NORTH;
		c.weightx = 0.1;
		c.gridx = 3;
		c.gridy = 3;
		add(repsLabel, c);

		JLabel notesLabel = new JLabel("           Notes           ");
		notesLabel.setSize(20, 12);
		//exerciseLabel.setFont(fieldFont);
		c.anchor = GridBagConstraints.NORTH;
		c.weightx = 0.5;
		c.gridx = 4;
		c.gridy = 3;
		add(notesLabel, c);
//		END ROW FOUR -- COLUMN LABELS

//		The data rows - Contain textareas and comboboxes for Exercise, Weight Type, Weight, Reps, and Notes
		currentRow = 4;
		addNewSet();
		
	}//end addComponentsToPane
	
	private class TextAreaHighlighter implements FocusListener {
		public void focusLost(FocusEvent e) {
			JTextArea textArea = 
		        (JTextArea)e.getSource();
			textArea.setBackground(NONDIMMEDBGCOLOR);
		}
		public void focusGained(FocusEvent e) {
			JTextArea textArea = 
		        (JTextArea)e.getSource();
			textArea.setBackground(ACTIVECOLOR);
			
			changesMade = true;
		}
	}
	
	private class ComboBoxHighlighter implements FocusListener {
		public void focusLost(FocusEvent e) {
			Component combobox = 
		        (Component)e.getSource();
			combobox.setBackground(NONDIMMEDBGCOLOR);
		}
		public void focusGained(FocusEvent e) {
			Component combobox = 
		        (Component)e.getSource();
			combobox.setBackground(ACTIVECOLOR);
			
			changesMade = true;
		}
	}
	
	private class SaveBeforeExit extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			if(changesMade) {
				int option = JOptionPane.showOptionDialog(
						Content_WeightliftingChart.this,
	                    "Do you want to save your changes before exitting?",
	                    "Save changes?", JOptionPane.YES_NO_CANCEL_OPTION,
	                    JOptionPane.WARNING_MESSAGE, null, null, null );
				
	            if(option == JOptionPane.YES_OPTION) {
	                boolean saved = saveData();
	                if(saved) {
	                	e.getWindow().dispose();
	                }
	            } else if(option == JOptionPane.NO_OPTION) {
	            	e.getWindow().dispose();
	            } else if(option == JOptionPane.CANCEL_OPTION) {
	            	//do nothing
	            }
			}
		}
	}
}//end workoutChartGUI
